import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
import seaborn as sns
import mplfinance as mpf
from datetime import datetime

# 设置中文显示
plt.rcParams['font.sans-serif'] = ['SimHei']  # 用来正常显示中文标签
plt.rcParams['axes.unicode_minus'] = False  # 用来正常显示负号

# (1) 读取文件，观察数据形状，输出前5行，并对定量变量进行描述性分析
def load_and_analyze_data(file_path):
    # 读取Excel文件
    df = pd.read_excel(file_path)
    
    print("数据形状:", df.shape)
    print("\n数据前5行:")
    print(df.head())
    
    # 对定量变量进行描述性分析
    print("\n定量变量描述性分析:")
    # 假设除了日期列外，其他都是定量变量
    numeric_cols = df.select_dtypes(include=['float64', 'int64']).columns
    descriptive_stats = df[numeric_cols].describe()
    print(descriptive_stats)
    
    return df, numeric_cols

# (2) 计算变量之间的相关系数，并绘制相关系数热力图
def correlation_analysis(df, numeric_cols):
    # 计算相关系数
    corr_matrix = df[numeric_cols].corr()
    print("\n变量相关系数矩阵:")
    print(corr_matrix)
    
    # 绘制相关系数热力图
    plt.figure(figsize=(12, 8))
    sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', fmt='.2f', square=True)
    plt.title('变量相关系数热力图')
    plt.tight_layout()
    plt.savefig('correlation_heatmap.png', dpi=300)
    plt.show()

# (3) 绘制2023年全年的收盘价时序图
def plot_2023_close_price(df):
    # 确保日期列格式正确
    if '日期' in df.columns:
        df['日期'] = pd.to_datetime(df['日期'])
        # 筛选2023年的数据
        df_2023 = df[df['日期'].dt.year == 2023]
        
        plt.figure(figsize=(14, 7))
        plt.plot(df_2023['日期'], df_2023['收盘价'], marker='o', linestyle='-', color='blue', markersize=3)
        plt.title('2023年比亚迪股价收盘价时序图')
        plt.xlabel('日期')
        plt.ylabel('收盘价')
        plt.grid(True, linestyle='--', alpha=0.7)
        plt.tight_layout()
        plt.savefig('2023_close_price.png', dpi=300)
        plt.show()
    else:
        print("未找到日期列，无法绘制2023年收盘价时序图")

# (4) 绘制2023年4月到2023年6月的K线图
def plot_k_line_2023_apr_jun(df):
    if '日期' in df.columns:
        # 确保日期列格式正确
        df['日期'] = pd.to_datetime(df['日期'])
        
        # 筛选2023年4月到6月的数据
        start_date = '2023-04-01'
        end_date = '2023-06-30'
        df_k_line = df[(df['日期'] >= start_date) & (df['日期'] <= end_date)]
        
        # 确保列名符合mplfinance的要求
        df_k_line = df_k_line.rename(columns={
            '日期': 'Date',
            '开盘价': 'Open',
            '最高价': 'High',
            '最低价': 'Low',
            '收盘价': 'Close',
            '成交量': 'Volume'
        })
        
        # 设置日期为索引
        df_k_line = df_k_line.set_index('Date')
        
        # 绘制K线图
        plt.figure(figsize=(14, 8))
        mpf.plot(df_k_line, type='candle', style='charles', title='2023年4月-6月比亚迪K线图',
                ylabel='价格', volume=True, ylabel_lower='成交量', savefig='k_line_chart.png')
        
        # 对K线图进行简单分析
        analyze_k_line(df_k_line)
    else:
        print("未找到日期列，无法绘制K线图")

# K线图分析函数
def analyze_k_line(df_k_line):
    print("\n2023年4月-6月K线图分析:")
    
    # 计算基本统计量
    price_change = df_k_line['Close'].iloc[-1] - df_k_line['Close'].iloc[0]
    percent_change = (price_change / df_k_line['Close'].iloc[0]) * 100
    
    print(f"起始收盘价: {df_k_line['Close'].iloc[0]:.2f}")
    print(f"结束收盘价: {df_k_line['Close'].iloc[-1]:.2f}")
    print(f"期间涨跌额: {price_change:.2f}")
    print(f"期间涨跌幅: {percent_change:.2f}%")
    
    # 找出最高价和最低价
    print(f"最高价: {df_k_line['High'].max():.2f} (出现日期: {df_k_line['High'].idxmax().strftime('%Y-%m-%d')})")
    print(f"最低价: {df_k_line['Low'].min():.2f} (出现日期: {df_k_line['Low'].idxmin().strftime('%Y-%m-%d')})")
    
    # 简单趋势分析
    if percent_change > 5:
        print("整体趋势: 上涨")
    elif percent_change < -5:
        print("整体趋势: 下跌")
    else:
        print("整体趋势: 震荡")

# 主函数
if __name__ == "__main__":
    file_path = "比亚迪后复权历史行情数据.xlsx"
    
    # 执行任务1
    df, numeric_cols = load_and_analyze_data(file_path)
    
    # 执行任务2
    correlation_analysis(df, numeric_cols)
    
    # 执行任务3
    plot_2023_close_price(df)
    
    # 执行任务4
    plot_k_line_2023_apr_jun(df)